package com.coffee.excel.executor;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.util.ConverterUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 直接用map接收数据
 * @author: songkui
 * @since: 2023/2/14 10:51
 */
@Slf4j
public class MochaAnalysisDataListener extends AnalysisEventListener<Map<Integer, String>> {
    /**
     * 最佳是1000， 然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = Integer.MAX_VALUE;
    private Map<Integer, Map<Integer, String>> cachedDataMap;  // key: rowIndex,  V: key: col, v: value
    private List<String> headList;
    private String title;

    public MochaAnalysisDataListener(Map<Integer, Map<Integer, String>> cachedDataMap,  List<String> head, String title) {
        this.cachedDataMap = cachedDataMap;
        this.headList = head;
        this.title = title;
    }

    /**
     * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
     *
     * @param exception
     * @param context
     * @throws Exception
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {

        Integer row = context.readRowHolder().getRowIndex();
        Map<Integer, String> rowData = new HashMap<>();
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            log.error("Row{} ，Column{} Analytic exception，data:{}", excelDataConvertException.getRowIndex(), excelDataConvertException.getColumnIndex());
            rowData.put(0, "数据解析异常，请检查");
            cachedDataMap.put(row, rowData);
        } else if (exception instanceof ExcelAnalysisStopException) {   //模板头解析错误则直接停止解析下一行
            rowData.put(0, "导入模板非最新模板， 请重新下载");
            cachedDataMap.put(row, rowData);
            throw new ExcelAnalysisStopException("导入模板非最新模板");
        } else {
            rowData.put(0, "读取异常：" + exception.getMessage());
            cachedDataMap.put(row, rowData);
            log.error("Other Exception:", exception.getMessage());
        }
    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        cachedDataMap.put(context.readRowHolder().getRowIndex(), data);
    }

    @SneakyThrows
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {

        Integer row = context.readRowHolder().getRowIndex();
        if (1 == row){
            Map<Integer, String> headStringMap = ConverterUtils.convertToStringMap(headMap, context);
            int i=0;
            for (String head : headList){
                if (!head.equals(headStringMap.get(i))){
                    log.error("Template error：Row{} Column{}  standard:[{} ] not[{}]", row, i, head, headStringMap.get(i));
                    throw new ExcelAnalysisStopException(title  +"导入模板非最新模板");
                }
                ++i;
            }
        }

    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("{} All data analysis completed！", title);
    }

}
